#ifndef __ITEMS_H
#define __ITEMS_H

typedef enum { 
	ITEM_NOTHING = 0,
	ITEM_WEAPON_CLOSE = 1, 
	ITEM_WEAPON_RANGE = 2,
	ITEM_ARMOR = 3,
	ITEM_AMULET = 4,
	ITEM_POTION = 5,
} ItemType;

/*
 * About damage types, weapons and armor
 * There are 3 different types of damage which work like a
 * rock-paper-scissors system: physical damage is good against
 * magical armor, magical damage is good against immaterial armor,
 * immaterial damage is good against physical armor.
 * Each weapon does damage in all 3 categories, and each armor prevents
 * damage in all 3 categories. The final damage of an attack is thus:
 * total_damage = physical_damage * physical_reduce + magic_damage * magic_reduce + immaterial_damage * immaterial_reduce
 * where the *_damage value is taken from the attacker's weapon and the
 * *_reduce value is taken from the victim's armor.
 * A weapon is inferred to be of the specific damage type in which it does the
 * greatest amount of damage. This weapon type is an information to the user
 * and does not affect gameplay. Similarly, armor also always has a type.
 * The system does not enforce the RPS balance; there can exist a weapon with
 * a physical type that is also does a great amount of magic damage against
 * immaterial armor.
 */
typedef enum {
	DAMAGE_PHYSICAL = 0,
	DAMAGE_MAGIC = 1,
	DAMAGE_IMMATERIAL = 2,
} DamageType;

// Special effects to be applied at various positions in the game code
typedef enum {
	EFFECT_WEAPON_NONE = 0,
} WeaponEffect;

typedef enum {
	EFFECT_ARMOR_NONE = 0,
} ArmorEffect;

typedef enum {
	EFFECT_AMULET_NONE = 0,
} AmuletEffect;

typedef enum {
	EFFECT_POTION_NONE = 0,
} PotionEffect;

typedef struct {
	// General info
	ItemType type;
	int icon_x;
	int icon_y;
	const char* name;

	// Detailled info
	//const char* file; // Weapons (frameset for attacks)
	int physical_damage; // Weapons
	int magic_damage; // Weapons
	int immaterial_damage; // Weapons
	double physical_reduce; // Armor. A value of 0.7 means that damage will be reduced to 70%.
	double magic_reduce; // Armor.
	double immaterial_reduce; // Armor.
	int cooldown; // Weapons, Potion
	int effect; // Weapons, Armor, Amulet, Potion
	
	// Auto-inferred attributes
	DamageType dmgtype;
} Item;

/* an item in slot X is also expected to be of type X */
typedef struct {
	int slot [5];
} Inventory;

#define WEAPONS_CLOSE_COUNT 25
#define WEAPONS_CLOSE_BEGIN 1
#define WEAPONS_CLOSE_END (WEAPONS_CLOSE_BEGIN + WEAPONS_CLOSE_COUNT)
#define WEAPONS_RANGE_COUNT 6
#define WEAPONS_RANGE_BEGIN 49
#define WEAPONS_RANGE_END (WEAPONS_RANGE_BEGIN + WEAPONS_RANGE_COUNT)
#define ARMORS_COUNT 0
#define ARMORS_BEGIN WEAPONS_RANGE_END
#define ARMORS_END (ARMORS_BEGIN + ARMORS_COUNT)
#define AMULETS_COUNT 0
#define AMULETS_BEGIN ARMORS_END
#define AMULETS_END (AMULETS_BEGIN + AMULETS_COUNT)
#define POTIONS_COUNT 0
#define POTIONS_BEGIN AMULETS_END
#define POTIONS_END (POTIONS_BEGIN + POTIONS_COUNT)

/* all the items in the game */
extern Item items [];

#endif
